package model;

import java.util.ArrayList;

import view.MarioListener;

public class Model {
	int score;
	long time;
	int lives;
	int coins;
	long start_time=0;
	public int width; //Spielfeldbreite
	
	private ArrayList<MarioListener> listener = new ArrayList<MarioListener>(); 
	
	MarioObject[][][] level;
	
	public Model(){
		this.score=0;
		this.start_time= System.nanoTime();
		this.lives = 3;
		this.coins = 0;

		this.loadLevel();
		
	}
	

	public boolean addModelChangeEventListener(MarioListener listener){
		
		return this.listener.add(listener);
	}
	
	public void modelChanged(){
		for(MarioListener a : listener) a.modelChanged();
	}

	public void loadLevel(){
		
		int level_width = 50;
		int level_height = 10;
		int dimensions = 4;
		this.width = level_width*50;
		this.level = new MarioObject[dimensions][level_width][level_height];

		for(int i=0;i<level_height;i++){//Start
			level[0][0][i]=new Obstacle(0,i,TYPE.DIRT);
		}
		
		for(int i=0;i<level_height;i++){//Ende
			level[0][level_width-1][i]=new Obstacle(level_width-1,i,TYPE.DIRT);
		}
		for(int i=0;i<level_width;i++){//boden
			level[0][i][9]=new Obstacle(i,9,TYPE.DIRT_GRASS);
		}
		
		
		level[0][13][8]=new Obstacle(13,8,TYPE.BLOCK);
		level[0][14][8]=new Obstacle(14,8,TYPE.BLOCK);
		level[0][18][8]=new Obstacle(18,8,TYPE.BLOCK);
		
		level[0][14][7]=new Obstacle(14,7,TYPE.BLOCK);
		level[0][15][6]=new Obstacle(15,6,TYPE.BLOCK);
		
		level[0][17][5]=new Obstacle(17,5,TYPE.BLOCK);
		level[0][20][5]=new Obstacle(20,5,TYPE.BLOCK);
		for(int i=10;i<level_width;i+=10){//alle 10 nen block
			level[0][i][8]=new Obstacle(i,8,TYPE.DIRT_GRASS);
		}
		
		//Spieler <- hardcoded auf die pos bis jetzt! no change oder im spielfed dann auch ändern
		level[3][1][7]=new Player(1,6,TYPE.PLAYER_SMALL);
		//Gegner
		level[2][0][1] = new Enemy(9,7,TYPE.ENEMY1);

		
		/*level.add( new Obstacle(0,8,TYPE.DIRT_GRASS) );
		for(int x=1;x<level_width;x++)
			level.add( new Obstacle(x,9,TYPE.DIRT_GRASS) );

		//level.add( new Obstacle(0,9,TYPE.DIRT) );
		level.add( new Obstacle(14,8,TYPE.BLOCK) );
		
		level.add( new Player(1,8,TYPE.PLAYER_SMALL) );
		level.add( new Enemy(8,8,TYPE.ENEMY1) );
		/*
		for(int i=0;i<13;i++)
			level.add( new Enemy(i,1,TYPE.ENEMY2,false,true) );
		for(int i=0;i<20;i++)
			level.add( new Obstacle(i,2,TYPE.DIRT_GRASS) );
		
		
		
		level[3][10][3] = new Enemy(10,3,TYPE.ENEMY2,false,true);

		level.add( new Obstacle(8,4,TYPE.DIRT_GRASS) );
		level.add( new Obstacle(9,4,TYPE.DIRT_GRASS) );
		level.add( new Obstacle(10,4,TYPE.DIRT_GRASS) );
		
		level.add( new Obstacle(12,8,TYPE.DIRT_GRASS) );
		level.add( new Obstacle(13,8,TYPE.DIRT_GRASS) );
		level.add( new Obstacle(12,9,TYPE.DIRT) );
		level.add( new Obstacle(13,9,TYPE.DIRT) );
		level.add( new Obstacle(14,9,TYPE.WATER) );
		level.add( new Obstacle(15,9,TYPE.WATER) );
		
		level.add( new Obstacle(15,6,TYPE.DIRT_GRASS) );
		level.add( new Obstacle(16,6,TYPE.DIRT_GRASS) );
		level.add( new Collectable(15,5,TYPE.COIN) );
		
		for(int y=8;y<level_height;y++)
			level.add( new Obstacle(3,y,TYPE.BLOCK) );
		
		for(int y=7;y<level_height;y++)
			level.add( new Obstacle(4,y,TYPE.BLOCK) );
		
		for(int y=6;y<level_height;y++)
			level.add( new Obstacle(5,y,TYPE.BLOCK) );
		
		level.add( new Collectable(5,5,TYPE.COIN) );
		
		level.add( new Obstacle(0,8,TYPE.BLOCK) );
		
		level.add( new Player(1,8,TYPE.PLAYER_SMALL,false) );
		level.add( new Enemy(9,8,TYPE.ENEMY1,false,true) );
		level.add( new Collectable(11,8,TYPE.COIN) );
		//level.add( new Enemy(11,8,TYPE.ENEMY2,false,true) );
		
		
		//Rest f�llen
				//level.add( new Obstacle(x,y,TYPE.TRANSPARENT) );
		
		*/
	}
	
	
	
	public MarioObject[][][] getLevel(){
		return level;
	}
	
	public int getScore(){
		return this.coins*10;
	}
	
	public long getTime(){
		return (System.nanoTime()-this.start_time)/((long) 1e9);
	}
	
	public int getCoins(){
		return this.coins;
	}
	public int getLivess(){
		return this.lives;
	}
	public void removeLive(){
		this.lives--;
	}
	
	public void addCoin(){
		this.coins++;
	}
	

}
